/******************************************************************************中
 * @brief: bsp io
 * @Author:   aple
 * @Date: 2021-06-14 18:06:21
 * @LastEditors: aple
 * @LastEditTime: 2023-03-16 08:31:07
 * @Verision: 1.0.0.0
 ******************************************************************************/
#define PORT_PIN_CTEAT
#include "bsp.h"
#include "bsp_io.h"
#include "iohandle.h"
#include "pincfg.h"
#include "mytype.h"

/*******************************************************************************
 * @brief  ext sim io
 *******************************************************************************/
uint8_t ext_port_out[4][8];
uint8_t ext_port_in[4];

void bsp_pin_mux_cfg(GPIO_TypeDef *port, uint32_t pin, uint8_t gpio_mux);

/*******************************************************************************
 * @brief  gpio cfg list
 *******************************************************************************/
static gpio_init_cfg_type gpio_cfg[] = {
	// LED
	{GPIOD, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, 0, GPIO_SPEED_FREQ_LOW, 1, GPIO_PIN_13},
	{GPIOD, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, 0, GPIO_SPEED_FREQ_LOW, 1, GPIO_PIN_14},

	// IIC
	{GPIOB, GPIO_MODE_OUTPUT_OD, GPIO_NOPULL, 0, GPIO_SPEED_FREQ_LOW, 1, GPIO_PIN_10},
	{GPIOB, GPIO_MODE_OUTPUT_OD, GPIO_NOPULL, 0, GPIO_SPEED_FREQ_LOW, 1, GPIO_PIN_11},

	// UART4
	//{GPIOA, GPIO_MODE_OUTPUT_OD, GPIO_NOPULL, GPIO_AF8_UART4, GPIO_SPEED_FREQ_HIGH, 1, GPIO_PIN_0 | GPIO_PIN_1},
	// UART1
	//{GPIOA, GPIO_MODE_OUTPUT_OD, GPIO_NOPULL, GPIO_AF7_USART1, GPIO_SPEED_FREQ_HIGH, 1, GPIO_PIN_9 | GPIO_PIN_10},

	// EXT IO
	{GPIOD, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, 0, GPIO_SPEED_FREQ_LOW, 1,
	 GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7},
	{GPIOD, GPIO_MODE_OUTPUT_PP, GPIO_NOPULL, 0, GPIO_SPEED_FREQ_LOW, 0,
	 /*GPIO_PIN_8 | GPIO_PIN_9 | */ GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12},
};

/*******************************************************************************
 * @brief  bsp_gpio_init
 * \param[in] us delay
 * \retval: none
 *******************************************************************************/
void bsp_gpio_init(void)
{
	int index;

	__HAL_RCC_GPIOA_CLK_ENABLE();
	__HAL_RCC_GPIOB_CLK_ENABLE();
	__HAL_RCC_GPIOC_CLK_ENABLE();
	__HAL_RCC_GPIOD_CLK_ENABLE();
	__HAL_RCC_GPIOE_CLK_ENABLE();
	__HAL_RCC_GPIOF_CLK_ENABLE();
	__HAL_RCC_GPIOG_CLK_ENABLE();
	__HAL_RCC_GPIOH_CLK_ENABLE();

	/*gpio cfg*/
	for (index = 0; index < sizeof(gpio_cfg) / sizeof(gpio_init_cfg_type); index++)
	{
		GPIO_InitTypeDef GPIO_InitStruct;

		GPIO_InitStruct.Pin = gpio_cfg[index].pin;
		GPIO_InitStruct.Mode = gpio_cfg[index].mode;
		GPIO_InitStruct.Pull = gpio_cfg[index].pull;
		GPIO_InitStruct.Speed = gpio_cfg[index].speed;
		GPIO_InitStruct.Alternate = gpio_cfg[index].af;

		HAL_GPIO_Init(gpio_cfg[index].port, &GPIO_InitStruct);

		if ((gpio_cfg[index].mode == GPIO_MODE_OUTPUT_PP) || (gpio_cfg[index].mode == GPIO_MODE_OUTPUT_OD))
		{
			if (gpio_cfg[index].val_init)
			{
				HAL_GPIO_WritePin(gpio_cfg[index].port, gpio_cfg[index].pin, GPIO_PIN_SET);
			}
			else
			{
				HAL_GPIO_WritePin(gpio_cfg[index].port, gpio_cfg[index].pin, GPIO_PIN_RESET);
			}
		}
	}
}

/*******************************************************************************
 * @brief  bsp_gpio
 * \param[in] us delay
 * \retval: none
 *******************************************************************************/
void bsp_pin_mux_cfg(GPIO_TypeDef *port, uint32_t pin, uint8_t gpio_mux)
{
	loop(16)
	{
		if ((1UL << index) & pin)
		{
			group_bits2_set(port->MODER, pin, 2UL);
			group_bits4_set(port->AFR[0], pin, gpio_mux);
		}
	}
}

/*******************************************************************************
 * @brief  bsp_gpio
 * \param[in] us delay
 * \retval: none
 *******************************************************************************/
void bsp_gpio_mode_out_pp(GPIO_TypeDef *port, uint8_t pin)
{
	intx_alloc();

	intx_disable();

	group_bits2_set(port->MODER, pin, 1UL);
	group_bits1_set(port->OTYPER, pin, 0UL);
	group_bits2_set(port->OSPEEDR, pin, 2UL);

	intx_enable();
}

void bsp_gpio_mode_out_od(GPIO_TypeDef *port, uint8_t pin)
{
	intx_alloc();

	intx_disable();

	group_bits2_set(port->MODER, pin, 1UL);
	group_bits1_set(port->OTYPER, pin, 1UL);
	group_bits2_set(port->OSPEEDR, pin, 2UL);

	intx_enable();
}

void bsp_gpio_mode_out_pp_spd(GPIO_TypeDef *port, uint8_t pin, uint32_t spd)
{
	intx_alloc();

	intx_disable();

	group_bits2_set(port->MODER, pin, 1UL);
	group_bits1_set(port->OTYPER, pin, 0UL);
	group_bits2_set(port->OSPEEDR, pin, spd);

	intx_enable();
}

void bsp_gpio_mode_out_od_spd(GPIO_TypeDef *port, uint8_t pin, uint32_t spd)
{
	intx_alloc();

	intx_disable();

	group_bits2_set(port->MODER, pin, 1UL);
	group_bits1_set(port->OTYPER, pin, 1UL);
	group_bits2_set(port->OSPEEDR, pin, spd);

	intx_enable();
}

void bsp_gpio_mode_in_up(GPIO_TypeDef *port, uint8_t pin)
{
	intx_alloc();

	intx_disable();

	group_bits2_set(port->MODER, pin, 0UL);
	group_bits2_set(port->PUPDR, pin, 1UL);

	intx_enable();
}

void bsp_gpio_mode_in_dn(GPIO_TypeDef *port, uint8_t pin)
{
	intx_alloc();

	intx_disable();

	group_bits2_set(port->MODER, pin, 0UL);
	group_bits2_set(port->PUPDR, pin, 2UL);

	intx_enable();
}

void bsp_gpio_mode_in_ft(GPIO_TypeDef *port, uint8_t pin)
{
	intx_alloc();

	intx_disable();

	group_bits2_set(port->MODER, pin, 0UL);
	group_bits2_set(port->PUPDR, pin, 0UL);

	intx_enable();
}

void bsp_gpio_mode_ain(GPIO_TypeDef *port, uint8_t pin)
{
	intx_alloc();

	intx_disable();

	group_bits2_set(port->MODER, pin, 3UL);
	group_bits2_set(port->PUPDR, pin, 0UL);

	intx_enable();
}

void bsp_gpio_mode_set(GPIO_TypeDef *port, uint8_t pin, char pm)
{
	switch (pm)
	{
	case PIN_MODE_IN_UP:
	{
		bsp_gpio_mode_in_up(port, pin);
		break;
	}
	case PIN_MODE_IN_DN:
	{
		bsp_gpio_mode_in_dn(port, pin);
		break;
	}
	case PIN_MODE_IN_FLOAT:
	{
		bsp_gpio_mode_in_ft(port, pin);
		break;
	}
	case PIN_MODE_IN_AIN:
	{
		bsp_gpio_mode_ain(port, pin);
		break;
	};
	case PIN_MODE_OUT_SL_PP:
	{
		bsp_gpio_mode_out_pp_spd(port, pin, 0);
		break;
	}
	case PIN_MODE_OUT_SL_OD:
	{
		bsp_gpio_mode_out_od_spd(port, pin, 0);
		break;
	}
	case PIN_MODE_OUT_SM_PP:
	{
		bsp_gpio_mode_out_pp_spd(port, pin, 1);
		break;
	}
	case PIN_MODE_OUT_SM_OD:
	{
		bsp_gpio_mode_out_od_spd(port, pin, 1);
		break;
	}
	case PIN_MODE_OUT_SH_PP:
	{
		bsp_gpio_mode_out_pp_spd(port, pin, 3);
		break;
	}
	case PIN_MODE_OUT_SH_OD:
	{
		bsp_gpio_mode_out_od_spd(port, pin, 3);
		break;
	}
	default:
	{
		break;
	}
	}
}

/*******************************************************************************
 * @brief  ext sim io
 *******************************************************************************/
uint8_t ext_io_out_get(char gp)
{
	uint8_t val = 0;

#define EXT_IO_OUT_BIT(n)    \
	if (ext_port_out[gp][n]) \
		val |= BIT(n);

	EXT_IO_OUT_BIT(0);
	EXT_IO_OUT_BIT(1);
	EXT_IO_OUT_BIT(2);
	EXT_IO_OUT_BIT(3);
	EXT_IO_OUT_BIT(4);
	EXT_IO_OUT_BIT(5);
	EXT_IO_OUT_BIT(6);
	EXT_IO_OUT_BIT(7);

	return val;
}
